home *** CD-ROM | disk | FTP | other *** search
- // Copyright (C) 1999-2000 Id Software, Inc.
- //
-
- /*****************************************************************************
- * name: ai_cmd.c
- *
- * desc: Quake3 bot AI
- *
- * $Archive: /source/code/game/ai_cmd.c $
- * $Author: Raduffy $
- * $Revision: 5 $
- * $Modtime: 1/14/00 5:27p $
- * $Date: 1/14/00 5:35p $
- *
- *****************************************************************************/
-
- #include "g_local.h"
- #include "botlib.h"
- #include "be_aas.h"
- #include "be_ea.h"
- #include "be_ai_char.h"
- #include "be_ai_chat.h"
- #include "be_ai_gen.h"
- #include "be_ai_goal.h"
- #include "be_ai_move.h"
- #include "be_ai_weap.h"
- //
- #include "ai_main.h"
- #include "ai_dmq3.h"
- #include "ai_chat.h"
- #include "ai_cmd.h"
- #include "ai_dmnet.h"
- #include "ai_team.h"
- //
- #include "chars.h" //characteristics
- #include "inv.h" //indexes into the inventory
- #include "syn.h" //synonyms
- #include "match.h" //string matching types and vars
-
-
- #ifdef DEBUG
- /*
- ==================
- BotPrintTeamGoal
- ==================
- */
- void BotPrintTeamGoal(bot_state_t *bs) {
- char netname[MAX_NETNAME];
- float t;
-
- ClientName(bs->client, netname, sizeof(netname));
- t = bs->teamgoal_time - trap_AAS_Time();
- switch(bs->ltgtype) {
- case LTG_TEAMHELP:
- {
- BotAI_Print(PRT_MESSAGE, "%s: I'm gonna help a team mate for %1.0f secs\n", netname, t);
- break;
- }
- case LTG_TEAMACCOMPANY:
- {
- BotAI_Print(PRT_MESSAGE, "%s: I'm gonna accompany a team mate for %1.0f secs\n", netname, t);
- break;
- }
- case LTG_GETFLAG:
- {
- BotAI_Print(PRT_MESSAGE, "%s: I'm gonna get the flag for %1.0f secs\n", netname, t);
- break;
- }
- case LTG_RUSHBASE:
- {
- BotAI_Print(PRT_MESSAGE, "%s: I'm gonna rush to the base for %1.0f secs\n", netname, t);
- break;
- }
- case LTG_RETURNFLAG:
- {
- BotAI_Print(PRT_MESSAGE, "%s: I'm gonna try to return the flag for %1.0f secs\n", netname, t);
- break;
- }
- case LTG_DEFENDKEYAREA:
- {
- BotAI_Print(PRT_MESSAGE, "%s: I'm gonna defend a key area for %1.0f secs\n", netname, t);
- break;
- }
- case LTG_GETITEM:
- {
- BotAI_Print(PRT_MESSAGE, "%s: I'm gonna get an item for %1.0f secs\n", netname, t);
- break;
- }
- case LTG_KILL:
- {
- BotAI_Print(PRT_MESSAGE, "%s: I'm gonna kill someone for %1.0f secs\n", netname, t);
- break;
- }
- case LTG_CAMP:
- case LTG_CAMPORDER:
- {
- BotAI_Print(PRT_MESSAGE, "%s: I'm gonna camp for %1.0f secs\n", netname, t);
- break;
- }
- case LTG_PATROL:
- {
- BotAI_Print(PRT_MESSAGE, "%s: I'm gonna patrol for %1.0f secs\n", netname, t);
- break;
- }
- default:
- {
- if (bs->ctfroam_time > trap_AAS_Time()) {
- t = bs->ctfroam_time - trap_AAS_Time();
- BotAI_Print(PRT_MESSAGE, "%s: I'm gonna roam for %1.0f secs\n", netname, t);
- }
- else {
- BotAI_Print(PRT_MESSAGE, "%s: I've got a regular goal\n", netname);
- }
- }
- }
- }
- #endif //DEBUG
-
- /*
- ==================
- BotGetItemTeamGoal
-
- FIXME: add stuff like "upper rocket launcher"
- "the rl near the railgun", "lower grenade launcher" etc.
- ==================
- */
- int BotGetItemTeamGoal(char *goalname, bot_goal_t *goal) {
- int i;
-
- if (!strlen(goalname)) return qfalse;
- i = -1;
- do {
- i = trap_BotGetLevelItemGoal(i, goalname, goal);
- if (i > 0) {
- //do NOT defend dropped items
- if (goal->flags & GFL_DROPPED)
- continue;
- return qtrue;
- }
- } while(i > 0);
- return qfalse;
- }
-
- /*
- ==================
- BotGetMessageTeamGoal
- ==================
- */
- int BotGetMessageTeamGoal(bot_state_t *bs, char *goalname, bot_goal_t *goal) {
- bot_waypoint_t *cp;
-
- if (BotGetItemTeamGoal(goalname, goal)) return qtrue;
-
- cp = BotFindWayPoint(bs->checkpoints, goalname);
- if (cp) {
- memcpy(goal, &cp->goal, sizeof(bot_goal_t));
- return qtrue;
- }
- return qfalse;
- }
-
- /*
- ==================
- BotGetTime
- ==================
- */
- float BotGetTime(bot_match_t *match) {
- bot_match_t timematch;
- char timestring[MAX_MESSAGE_SIZE];
- float t;
-
- //if the matched string has a time
- if (match->subtype & ST_TIME) {
- //get the time string
- trap_BotMatchVariable(match, TIME, timestring, MAX_MESSAGE_SIZE);
- //match it to find out if the time is in seconds or minutes
- if (trap_BotFindMatch(timestring, &timematch, MTCONTEXT_TIME)) {
- if (timematch.type == MSG_FOREVER) {
- t = 99999999;
- }
- else {
- trap_BotMatchVariable(&timematch, TIME, timestring, MAX_MESSAGE_SIZE);
- if (timematch.type == MSG_MINUTES) t = atof(timestring) * 60;
- else if (timematch.type == MSG_SECONDS) t = atof(timestring);
- else t = 0;
- }
- //if there's a valid time
- if (t > 0) return trap_AAS_Time() + t;
- }
- }
- return 0;
- }
-
- /*
- ==================
- FindClientByName
- ==================
- */
- int FindClientByName(char *name) {
- int i;
- char buf[MAX_INFO_STRING];
- static int maxclients;
-
- if (!maxclients)
- maxclients = trap_Cvar_VariableIntegerValue("sv_maxclients");
- for (i = 0; i < maxclients && i < MAX_CLIENTS; i++) {
- ClientName(i, buf, sizeof(buf));
- if (!Q_stricmp(buf, name)) return i;
- }
- for (i = 0; i < maxclients && i < MAX_CLIENTS; i++) {
- ClientName(i, buf, sizeof(buf));
- if (stristr(buf, name)) return i;
- }
- return -1;
- }
-
- /*
- ==================
- FindEnemyByName
- ==================
- */
- int FindEnemyByName(bot_state_t *bs, char *name) {
- int i;
- char buf[MAX_INFO_STRING];
- static int maxclients;
-
- if (!maxclients)
- maxclients = trap_Cvar_VariableIntegerValue("sv_maxclients");
- for (i = 0; i < maxclients && i < MAX_CLIENTS; i++) {
- if (BotSameTeam(bs, i)) continue;
- ClientName(i, buf, sizeof(buf));
- if (!Q_stricmp(buf, name)) return i;
- }
- for (i = 0; i < maxclients && i < MAX_CLIENTS; i++) {
- if (BotSameTeam(bs, i)) continue;
- ClientName(i, buf, sizeof(buf));
- if (stristr(buf, name)) return i;
- }
- return -1;
- }
-
- /*
- ==================
- NumPlayersOnSameTeam
- ==================
- */
- int NumPlayersOnSameTeam(bot_state_t *bs) {
- int i, num;
- char buf[MAX_INFO_STRING];
- static int maxclients;
-
- if (!maxclients)
- maxclients = trap_Cvar_VariableIntegerValue("sv_maxclients");
-
- num = 0;
- for (i = 0; i < maxclients && i < MAX_CLIENTS; i++) {
- trap_GetConfigstring(CS_PLAYERS+i, buf, MAX_INFO_STRING);
- if (strlen(buf)) {
- if (BotSameTeam(bs, i+1)) num++;
- }
- }
- return num;
- }
-
- /*
- ==================
- TeamPlayIsOn
- ==================
- */
- int BotGetPatrolWaypoints(bot_state_t *bs, bot_match_t *match) {
- char keyarea[MAX_MESSAGE_SIZE];
- int patrolflags;
- bot_waypoint_t *wp, *newwp, *newpatrolpoints;
- bot_match_t keyareamatch;
- bot_goal_t goal;
-
- newpatrolpoints = NULL;
- patrolflags = 0;
- //
- trap_BotMatchVariable(match, KEYAREA, keyarea, MAX_MESSAGE_SIZE);
- //
- while(1) {
- if (!trap_BotFindMatch(keyarea, &keyareamatch, MTCONTEXT_PATROLKEYAREA)) {
- trap_EA_SayTeam(bs->client, "what do you say?");
- BotFreeWaypoints(newpatrolpoints);
- bs->patrolpoints = NULL;
- return qfalse;
- }
- trap_BotMatchVariable(&keyareamatch, KEYAREA, keyarea, MAX_MESSAGE_SIZE);
- if (!BotGetMessageTeamGoal(bs, keyarea, &goal)) {
- //BotAI_BotInitialChat(bs, "cannotfind", keyarea, NULL);
- //trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
- BotFreeWaypoints(newpatrolpoints);
- bs->patrolpoints = NULL;
- return qfalse;
- }
- //create a new waypoint
- newwp = BotCreateWayPoint(keyarea, goal.origin, goal.areanum);
- //add the waypoint to the patrol points
- newwp->next = NULL;
- for (wp = newpatrolpoints; wp && wp->next; wp = wp->next);
- if (!wp) {
- newpatrolpoints = newwp;
- newwp->prev = NULL;
- }
- else {
- wp->next = newwp;
- newwp->prev = wp;
- }
- //
- if (keyareamatch.subtype & ST_BACK) {
- patrolflags = PATROL_LOOP;
- break;
- }
- else if (keyareamatch.subtype & ST_REVERSE) {
- patrolflags = PATROL_REVERSE;
- break;
- }
- else if (keyareamatch.subtype & ST_MORE) {
- trap_BotMatchVariable(&keyareamatch, MORE, keyarea, MAX_MESSAGE_SIZE);
- }
- else {
- break;
- }
- }
- //
- if (!newpatrolpoints || !newpatrolpoints->next) {
- trap_EA_SayTeam(bs->client, "I need more key points to patrol\n");
- BotFreeWaypoints(newpatrolpoints);
- newpatrolpoints = NULL;
- return qfalse;
- }
- //
- BotFreeWaypoints(bs->patrolpoints);
- bs->patrolpoints = newpatrolpoints;
- //
- bs->curpatrolpoint = bs->patrolpoints;
- bs->patrolflags = patrolflags;
- //
- return qtrue;
- }
-
- /*
- ==================
- BotAddressedToBot
- ==================
- */
- int BotAddressedToBot(bot_state_t *bs, bot_match_t *match) {
- char addressedto[MAX_MESSAGE_SIZE];
- char netname[MAX_MESSAGE_SIZE];
- char name[MAX_MESSAGE_SIZE];
- char botname[128];
- int client;
- bot_match_t addresseematch;
-
- trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
- client = ClientFromName(netname);
- if (client < 0) return qfalse;
- if (!BotSameTeam(bs, client)) return qfalse;
- //if the message is addressed to someone
- if (match->subtype & ST_ADDRESSED) {
- trap_BotMatchVariable(match, ADDRESSEE, addressedto, sizeof(addressedto));
- //the name of this bot
- ClientName(bs->client, botname, 128);
- //
- while(trap_BotFindMatch(addressedto, &addresseematch, MTCONTEXT_ADDRESSEE)) {
- if (addresseematch.type == MSG_EVERYONE) {
- return qtrue;
- }
- else if (addresseematch.type == MSG_MULTIPLENAMES) {
- trap_BotMatchVariable(&addresseematch, TEAMMATE, name, sizeof(name));
- if (strlen(name)) {
- if (stristr(botname, name)) return qtrue;
- if (stristr(bs->subteam, name)) return qtrue;
- }
- trap_BotMatchVariable(&addresseematch, MORE, addressedto, MAX_MESSAGE_SIZE);
- }
- else {
- trap_BotMatchVariable(&addresseematch, TEAMMATE, name, MAX_MESSAGE_SIZE);
- if (strlen(name)) {
- if (stristr(botname, name)) return qtrue;
- if (stristr(bs->subteam, name)) return qtrue;
- }
- break;
- }
- }
- //Com_sprintf(buf, sizeof(buf), "not addressed to me but %s", addressedto);
- //trap_EA_Say(bs->client, buf);
- return qfalse;
- }
- else {
- //make sure not everyone reacts to this message
- if (random() > (float ) 1.0 / (NumPlayersOnSameTeam(bs)-1)) return qfalse;
- }
- return qtrue;
- }
-
- /*
- ==================
- BotGPSToPosition
- ==================
- */
- int BotGPSToPosition(char *buf, vec3_t position) {
- int i, j = 0;
- int num, sign;
-
- for (i = 0; i < 3; i++) {
- num = 0;
- while(buf[j] == ' ') j++;
- if (buf[j] == '-') {
- j++;
- sign = -1;
- }
- else {
- sign = 1;
- }
- while (buf[j]) {
- if (buf[j] >= '0' && buf[j] <= '9') {
- num = num * 10 + buf[j] - '0';
- j++;
- }
- else {
- j++;
- break;
- }
- }
- BotAI_Print(PRT_MESSAGE, "%d\n", sign * num);
- position[i] = (float) sign * num;
- }
- return qtrue;
- }
-
- /*
- ==================
- BotMatch_HelpAccompany
- ==================
- */
- void BotMatch_HelpAccompany(bot_state_t *bs, bot_match_t *match) {
- int client, other, areanum;
- char teammate[MAX_MESSAGE_SIZE], netname[MAX_MESSAGE_SIZE];
- char itemname[MAX_MESSAGE_SIZE];
- bot_match_t teammatematch;
- aas_entityinfo_t entinfo;
-
- if (!TeamPlayIsOn()) return;
- //if not addressed to this bot
- if (!BotAddressedToBot(bs, match)) return;
- //get the team mate name
- trap_BotMatchVariable(match, TEAMMATE, teammate, sizeof(teammate));
- //get the client to help
- if (trap_BotFindMatch(teammate, &teammatematch, MTCONTEXT_TEAMMATE) &&
- //if someone asks for him or herself
- teammatematch.type == MSG_ME) {
- //get the netname
- trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
- client = ClientFromName(netname);
- other = qfalse;
- }
- else {
- //asked for someone else
- client = FindClientByName(teammate);
- //if this is the bot self
- if (client == bs->client) {
- other = qfalse;
- }
- else if (!BotSameTeam(bs, client)) {
- //FIXME: say "I don't help the enemy"
- return;
- }
- else {
- other = qtrue;
- }
- }
- //if the bot doesn't know who to help (FindClientByName returned -1)
- if (client < 0) {
- if (other) BotAI_BotInitialChat(bs, "whois", teammate, NULL);
- else BotAI_BotInitialChat(bs, "whois", netname, NULL);
- trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
- return;
- }
- //don't help or accompany yourself
- if (client == bs->client) {
- return;
- }
- //
- bs->teamgoal.entitynum = -1;
- BotEntityInfo(client, &entinfo);
- //if info is valid (in PVS)
- if (entinfo.valid) {
- areanum = BotPointAreaNum(entinfo.origin);
- if (areanum && trap_AAS_AreaReachability(areanum)) {
- bs->teamgoal.entitynum = client;
- bs->teamgoal.areanum = areanum;
- VectorCopy(entinfo.origin, bs->teamgoal.origin);
- VectorSet(bs->teamgoal.mins, -8, -8, -8);
- VectorSet(bs->teamgoal.maxs, 8, 8, 8);
- }
- }
- //if no teamgoal yet
- if (bs->teamgoal.entitynum < 0) {
- //if near an item
- if (match->subtype & ST_NEARITEM) {
- //get the match variable
- trap_BotMatchVariable(match, ITEM, itemname, sizeof(itemname));
- //
- if (!BotGetMessageTeamGoal(bs, itemname, &bs->teamgoal)) {
- //BotAI_BotInitialChat(bs, "cannotfind", itemname, NULL);
- //trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
- return;
- }
- }
- }
- //
- if (bs->teamgoal.entitynum < 0) {
- if (other) BotAI_BotInitialChat(bs, "whereis", teammate, NULL);
- else BotAI_BotInitialChat(bs, "whereareyou", netname, NULL);
- trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
- return;
- }
- //the team mate
- bs->teammate = client;
- //last time the team mate was assumed visible
- bs->teammatevisible_time = trap_AAS_Time();
- //set the time to send a message to the team mates
- bs->teammessage_time = trap_AAS_Time() + 2 * random();
- //get the team goal time
- bs->teamgoal_time = BotGetTime(match);
- //set the ltg type
- if (match->type == MSG_HELP) {
- bs->ltgtype = LTG_TEAMHELP;
- if (!bs->teamgoal_time) bs->teamgoal_time = trap_AAS_Time() + TEAM_HELP_TIME;
- }
- else {
- bs->ltgtype = LTG_TEAMACCOMPANY;
- if (!bs->teamgoal_time) bs->teamgoal_time = trap_AAS_Time() + TEAM_ACCOMPANY_TIME;
- bs->formation_dist = 3.5 * 32; //3.5 meter
- bs->arrive_time = 0;
- }
- #ifdef DEBUG
- BotPrintTeamGoal(bs);
- #endif //DEBUG
- }
-
- /*
- ==================
- BotMatch_DefendKeyArea
- ==================
- */
- void BotMatch_DefendKeyArea(bot_state_t *bs, bot_match_t *match) {
- char itemname[MAX_MESSAGE_SIZE];
-
- if (!TeamPlayIsOn()) return;
- //if not addressed to this bot
- if (!BotAddressedToBot(bs, match)) return;
- //get the match variable
- trap_BotMatchVariable(match, KEYAREA, itemname, sizeof(itemname));
- //
- if (!BotGetMessageTeamGoal(bs, itemname, &bs->teamgoal)) {
- //BotAI_BotInitialChat(bs, "cannotfind", itemname, NULL);
- //trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
- return;
- }
- //set the time to send a message to the team mates
- bs->teammessage_time = trap_AAS_Time() + 2 * random();
- //set the ltg type
- bs->ltgtype = LTG_DEFENDKEYAREA;
- //get the team goal time
- bs->teamgoal_time = BotGetTime(match);
- //set the team goal time
- if (!bs->teamgoal_time) bs->teamgoal_time = trap_AAS_Time() + TEAM_DEFENDKEYAREA_TIME;
- //away from defending
- bs->defendaway_time = 0;
- #ifdef DEBUG
- BotPrintTeamGoal(bs);
- #endif //DEBUG
- }
-
- /*
- ==================
- BotMatch_GetItem
- ==================
- */
- void BotMatch_GetItem(bot_state_t *bs, bot_match_t *match) {
- char itemname[MAX_MESSAGE_SIZE];
-
- if (!TeamPlayIsOn()) return;
- //if not addressed to this bot
- if (!BotAddressedToBot(bs, match)) return;
- //get the match variable
- trap_BotMatchVariable(match, ITEM, itemname, sizeof(itemname));
- //
- if (!BotGetMessageTeamGoal(bs, itemname, &bs->teamgoal)) {
- //BotAI_BotInitialChat(bs, "cannotfind", itemname, NULL);
- //trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
- return;
- }
- //set the time to send a message to the team mates
- bs->teammessage_time = trap_AAS_Time() + 2 * random();
- //set the ltg type
- bs->ltgtype = LTG_GETITEM;
- //set the team goal time
- bs->teamgoal_time = trap_AAS_Time() + TEAM_GETITEM_TIME;
- #ifdef DEBUG
- BotPrintTeamGoal(bs);
- #endif //DEBUG
- }
-
- /*
- ==================
- BotMatch_Camp
- ==================
- */
- void BotMatch_Camp(bot_state_t *bs, bot_match_t *match) {
- int client, areanum;
- char netname[MAX_MESSAGE_SIZE];
- char itemname[MAX_MESSAGE_SIZE];
- aas_entityinfo_t entinfo;
-
- if (!TeamPlayIsOn()) return;
- //if not addressed to this bot
- if (!BotAddressedToBot(bs, match)) return;
- //
- trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
- //asked for someone else
- client = FindClientByName(netname);
- //if there's no valid client with this name
- if (client < 0) {
- BotAI_BotInitialChat(bs, "whois", netname, NULL);
- trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
- return;
- }
- //get the match variable
- trap_BotMatchVariable(match, KEYAREA, itemname, sizeof(itemname));
- //in CTF it could be the base
- if (match->subtype & ST_THERE) {
- //camp at the spot the bot is currently standing
- bs->teamgoal.entitynum = bs->entitynum;
- bs->teamgoal.areanum = bs->areanum;
- VectorCopy(bs->origin, bs->teamgoal.origin);
- VectorSet(bs->teamgoal.mins, -8, -8, -8);
- VectorSet(bs->teamgoal.maxs, 8, 8, 8);
- }
- else if (match->subtype & ST_HERE) {
- //if this is the bot self
- if (client == bs->client) return;
- //
- bs->teamgoal.entitynum = -1;
- BotEntityInfo(client, &entinfo);
- //if info is valid (in PVS)
- if (entinfo.valid) {
- areanum = BotPointAreaNum(entinfo.origin);
- if (areanum && trap_AAS_AreaReachability(areanum)) {
- //NOTE: just cheat and assume the bot knows where the person is
- //if (BotEntityVisible(bs->entitynum, bs->eye, bs->viewangles, 360, client)) {
- bs->teamgoal.entitynum = client;
- bs->teamgoal.areanum = areanum;
- VectorCopy(entinfo.origin, bs->teamgoal.origin);
- VectorSet(bs->teamgoal.mins, -8, -8, -8);
- VectorSet(bs->teamgoal.maxs, 8, 8, 8);
- //}
- }
- }
- //if the other is not visible
- if (bs->teamgoal.entitynum < 0) {
- BotAI_BotInitialChat(bs, "whereareyou", netname, NULL);
- trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
- return;
- }
- }
- else if (!BotGetMessageTeamGoal(bs, itemname, &bs->teamgoal)) {
- //BotAI_BotInitialChat(bs, "cannotfind", itemname, NULL);
- //trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
- return;
- }
- //set the time to send a message to the team mates
- bs->teammessage_time = trap_AAS_Time() + 2 * random();
- //set the ltg type
- bs->ltgtype = LTG_CAMPORDER;
- //get the team goal time
- bs->teamgoal_time = BotGetTime(match);
- //set the team goal time
- if (!bs->teamgoal_time) bs->teamgoal_time = trap_AAS_Time() + TEAM_CAMP_TIME;
- //the teammate that requested the camping
- bs->teammate = client;
- //not arrived yet
- bs->arrive_time = 0;
- //
- #ifdef DEBUG
- BotPrintTeamGoal(bs);
- #endif //DEBUG
- }
-
- /*
- ==================
- BotMatch_Patrol
- ==================
- */
- void BotMatch_Patrol(bot_state_t *bs, bot_match_t *match) {
- if (!TeamPlayIsOn()) return;
- //if not addressed to this bot
- if (!BotAddressedToBot(bs, match)) return;
- //get the patrol waypoints
- if (!BotGetPatrolWaypoints(bs, match)) return;
- //set the time to send a message to the team mates
- bs->teammessage_time = trap_AAS_Time() + 2 * random();
- //set the ltg type
- bs->ltgtype = LTG_PATROL;
- //get the team goal time
- bs->teamgoal_time = BotGetTime(match);
- //set the team goal time if not set already
- if (!bs->teamgoal_time) bs->teamgoal_time = trap_AAS_Time() + TEAM_PATROL_TIME;
- //
- #ifdef DEBUG
- BotPrintTeamGoal(bs);
- #endif //DEBUG
- }
-
- /*
- ==================
- BotMatch_GetFlag
- ==================
- */
- void BotMatch_GetFlag(bot_state_t *bs, bot_match_t *match) {
- //if not in CTF mode
- if (gametype != GT_CTF || !ctf_redflag.areanum || !ctf_blueflag.areanum) return;
- //if not addressed to this bot
- if (!BotAddressedToBot(bs, match)) return;
- //set the time to send a message to the team mates
- bs->teammessage_time = trap_AAS_Time() + 2 * random();
- //set the ltg type
- bs->ltgtype = LTG_GETFLAG;
- //set the team goal time
- bs->teamgoal_time = trap_AAS_Time() + CTF_GETFLAG_TIME;
- #ifdef DEBUG
- BotPrintTeamGoal(bs);
- #endif //DEBUG
- }
-
- /*
- ==================
- BotMatch_RushBase
- ==================
- */
- void BotMatch_RushBase(bot_state_t *bs, bot_match_t *match) {
- //if not in CTF mode
- if (gametype != GT_CTF || !ctf_redflag.areanum || !ctf_blueflag.areanum) return;
- //if not addressed to this bot
- if (!BotAddressedToBot(bs, match)) return;
- //set the time to send a message to the team mates
- bs->teammessage_time = trap_AAS_Time() + 2 * random();
- //set the ltg type
- bs->ltgtype = LTG_RUSHBASE;
- //set the team goal time
- bs->teamgoal_time = trap_AAS_Time() + CTF_RUSHBASE_TIME;
- bs->rushbaseaway_time = 0;
- #ifdef DEBUG
- BotPrintTeamGoal(bs);
- #endif //DEBUG
- }
-
- /*
- ==================
- BotMatch_TaskPreference
- ==================
- */
- void BotMatch_TaskPreference(bot_state_t *bs, bot_match_t *match) {
- char netname[MAX_NETNAME];
- char teammatename[MAX_MESSAGE_SIZE];
- int teammate, preference;
-
- ClientName(bs->client, netname, sizeof(netname));
- if (Q_stricmp(netname, bs->teamleader) != 0) return;
-
- trap_BotMatchVariable(match, NETNAME, teammatename, sizeof(teammatename));
- teammate = ClientFromName(teammatename);
- if (teammate < 0) return;
-
- preference = BotGetTeamMateCTFPreference(bs, teammate);
- switch(match->subtype)
- {
- case ST_DEFENDER:
- {
- preference &= ~CTFTP_ATTACKER;
- preference |= CTFTP_DEFENDER;
- break;
- }
- case ST_ATTACKER:
- {
- preference &= ~CTFTP_DEFENDER;
- preference |= CTFTP_ATTACKER;
- break;
- }
- case ST_ROAMER:
- {
- preference &= ~(CTFTP_ATTACKER|CTFTP_DEFENDER);
- break;
- }
- }
- BotSetTeamMateCTFPreference(bs, teammate, preference);
- //
- EasyClientName(teammate, teammatename, sizeof(teammatename));
- BotAI_BotInitialChat(bs, "keepinmind", teammatename, NULL);
- trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
- }
-
- /*
- ==================
- BotMatch_ReturnFlag
- ==================
- */
- void BotMatch_ReturnFlag(bot_state_t *bs, bot_match_t *match) {
- //if not in CTF mode
- if (gametype != GT_CTF) return;
- //if not addressed to this bot
- if (!BotAddressedToBot(bs, match)) return;
- //set the time to send a message to the team mates
- bs->teammessage_time = trap_AAS_Time() + 2 * random();
- //set the ltg type
- bs->ltgtype = LTG_RETURNFLAG;
- //set the team goal time
- bs->teamgoal_time = trap_AAS_Time() + CTF_RETURNFLAG_TIME;
- bs->rushbaseaway_time = 0;
- #ifdef DEBUG
- BotPrintTeamGoal(bs);
- #endif //DEBUG
- }
-
- /*
- ==================
- BotMatch_JoinSubteam
- ==================
- */
- void BotMatch_JoinSubteam(bot_state_t *bs, bot_match_t *match) {
- char teammate[MAX_MESSAGE_SIZE];
-
- if (!TeamPlayIsOn()) return;
- //if not addressed to this bot
- if (!BotAddressedToBot(bs, match)) return;
- //get the sub team name
- trap_BotMatchVariable(match, TEAMNAME, teammate, MAX_MESSAGE_SIZE);
- //set the sub team name
- strncpy(bs->subteam, teammate, 32);
- bs->subteam[31] = '\0';
- //
- BotAI_BotInitialChat(bs, "joinedteam", teammate, NULL);
- trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
- }
-
- /*
- ==================
- BotMatch_LeaveSubteam
- ==================
- */
- void BotMatch_LeaveSubteam(bot_state_t *bs, bot_match_t *match) {
- if (!TeamPlayIsOn()) return;
- //if not addressed to this bot
- if (!BotAddressedToBot(bs, match)) return;
- //
- if (strlen(bs->subteam))
- {
- BotAI_BotInitialChat(bs, "leftteam", bs->subteam, NULL);
- } //end if
- trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
- strcpy(bs->subteam, "");
- }
-
- /*
- ==================
- BotMatch_LeaveSubteam
- ==================
- */
- void BotMatch_WhichTeam(bot_state_t *bs, bot_match_t *match) {
- if (!TeamPlayIsOn()) return;
- //if not addressed to this bot
- if (!BotAddressedToBot(bs, match)) return;
- //
- if (strlen(bs->subteam)) {
- BotAI_BotInitialChat(bs, "inteam", bs->subteam, NULL);
- }
- else {
- BotAI_BotInitialChat(bs, "noteam", NULL);
- }
- trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
- }
-
- /*
- ==================
- BotMatch_CheckPoint
- ==================
- */
- void BotMatch_CheckPoint(bot_state_t *bs, bot_match_t *match) {
- int areanum;
- char buf[MAX_MESSAGE_SIZE];
- vec3_t position;
- bot_waypoint_t *cp;
-
- if (!TeamPlayIsOn()) return;
- //
- trap_BotMatchVariable(match, POSITION, buf, MAX_MESSAGE_SIZE);
- VectorClear(position);
- //BotGPSToPosition(buf, position);
- sscanf(buf, "%f %f %f", &position[0], &position[1], &position[2]);
- position[2] += 0.5;
- areanum = BotPointAreaNum(position);
- if (!areanum) {
- if (BotAddressedToBot(bs, match)) {
- BotAI_BotInitialChat(bs, "checkpoint_invalid", NULL);
- trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
- }
- return;
- }
- //
- trap_BotMatchVariable(match, NAME, buf, MAX_MESSAGE_SIZE);
- //check if there already exists a checkpoint with this name
- cp = BotFindWayPoint(bs->checkpoints, buf);
- if (cp) {
- if (cp->next) cp->next->prev = cp->prev;
- if (cp->prev) cp->prev->next = cp->next;
- else bs->checkpoints = cp->next;
- cp->inuse = qfalse;
- }
- //create a new check point
- cp = BotCreateWayPoint(buf, position, areanum);
- //add the check point to the bot's known chech points
- cp->next = bs->checkpoints;
- if (bs->checkpoints) bs->checkpoints->prev = cp;
- bs->checkpoints = cp;
- //
- if (BotAddressedToBot(bs, match)) {
- Com_sprintf(buf, sizeof(buf), "%1.0f %1.0f %1.0f", cp->goal.origin[0],
- cp->goal.origin[1],
- cp->goal.origin[2]);
-
- BotAI_BotInitialChat(bs, "checkpoint_confirm", cp->name, buf, NULL);
- trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
- }
- }
-
- /*
- ==================
- BotMatch_FormationSpace
- ==================
- */
- void BotMatch_FormationSpace(bot_state_t *bs, bot_match_t *match) {
- char buf[MAX_MESSAGE_SIZE];
- float space;
-
- if (!TeamPlayIsOn()) return;
- //if not addressed to this bot
- if (!BotAddressedToBot(bs, match)) return;
- //
- trap_BotMatchVariable(match, NUMBER, buf, MAX_MESSAGE_SIZE);
- //if it's the distance in feet
- if (match->subtype & ST_FEET) space = 0.3048 * 32 * atof(buf);
- //else it's in meters
- else space = 32 * atof(buf);
- //check if the formation intervening space is valid
- if (space < 48 || space > 500) space = 100;
- bs->formation_dist = space;
- }
-
- /*
- ==================
- BotMatch_Dismiss
- ==================
- */
- void BotMatch_Dismiss(bot_state_t *bs, bot_match_t *match) {
- if (!TeamPlayIsOn()) return;
- //if not addressed to this bot
- if (!BotAddressedToBot(bs, match)) return;
- //
- bs->ltgtype = 0;
- bs->lead_time = 0;
- //
- BotAI_BotInitialChat(bs, "dismissed", NULL);
- trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
- }
-
- /*
- ==================
- BotMatch_StartTeamLeaderShip
- ==================
- */
- void BotMatch_StartTeamLeaderShip(bot_state_t *bs, bot_match_t *match) {
- int client;
- char teammate[MAX_MESSAGE_SIZE];
-
- if (!TeamPlayIsOn()) return;
- //if chats for him or herself
- if (match->subtype & ST_I) {
- //get the team mate that will be the team leader
- trap_BotMatchVariable(match, NETNAME, teammate, sizeof(teammate));
- strncpy(bs->teamleader, teammate, sizeof(bs->teamleader));
- bs->teamleader[sizeof(bs->teamleader)] = '\0';
- }
- //chats for someone else
- else {
- //get the team mate that will be the team leader
- trap_BotMatchVariable(match, TEAMMATE, teammate, sizeof(teammate));
- client = FindClientByName(teammate);
- if (client >= 0) ClientName(client, bs->teamleader, sizeof(bs->teamleader));
- }
- }
-
- /*
- ==================
- BotMatch_StopTeamLeaderShip
- ==================
- */
- void BotMatch_StopTeamLeaderShip(bot_state_t *bs, bot_match_t *match) {
- int client;
- char teammate[MAX_MESSAGE_SIZE];
- char netname[MAX_MESSAGE_SIZE];
-
- if (!TeamPlayIsOn()) return;
- //get the team mate that stops being the team leader
- trap_BotMatchVariable(match, TEAMMATE, teammate, sizeof(teammate));
- //if chats for him or herself
- if (match->subtype & ST_I) {
- trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
- client = FindClientByName(netname);
- }
- //chats for someone else
- else {
- client = FindClientByName(teammate);
- } //end else
- if (client >= 0) {
- if (!Q_stricmp(bs->teamleader, ClientName(client, netname, sizeof(netname)))) {
- bs->teamleader[0] = '\0';
- }
- }
- }
-
- /*
- ==================
- BotMatch_WhoIsTeamLeader
- ==================
- */
- void BotMatch_WhoIsTeamLeader(bot_state_t *bs, bot_match_t *match) {
- char netname[MAX_MESSAGE_SIZE];
-
- if (!TeamPlayIsOn()) return;
-
- ClientName(bs->client, netname, sizeof(netname));
- //if this bot IS the team leader
- if (!Q_stricmp(netname, bs->teamleader)) {
- trap_EA_SayTeam(bs->client, "I'm the team leader\n");
- }
- }
-
- /*
- ==================
- BotMatch_WhatAreYouDoing
- ==================
- */
- void BotMatch_WhatAreYouDoing(bot_state_t *bs, bot_match_t *match) {
- char netname[MAX_MESSAGE_SIZE];
- char goalname[MAX_MESSAGE_SIZE];
-
- //if not addressed to this bot
- if (!BotAddressedToBot(bs, match)) return;
- //
- switch(bs->ltgtype) {
- case LTG_TEAMHELP:
- {
- EasyClientName(bs->teammate, netname, sizeof(netname));
- BotAI_BotInitialChat(bs, "helping", netname, NULL);
- break;
- }
- case LTG_TEAMACCOMPANY:
- {
- EasyClientName(bs->teammate, netname, sizeof(netname));
- BotAI_BotInitialChat(bs, "accompanying", netname, NULL);
- break;
- }
- case LTG_DEFENDKEYAREA:
- {
- trap_BotGoalName(bs->teamgoal.number, goalname, sizeof(goalname));
- BotAI_BotInitialChat(bs, "defending", goalname, NULL);
- break;
- }
- case LTG_GETITEM:
- {
- trap_BotGoalName(bs->teamgoal.number, goalname, sizeof(goalname));
- BotAI_BotInitialChat(bs, "gettingitem", goalname, NULL);
- break;
- }
- case LTG_KILL:
- {
- ClientName(bs->teamgoal.entitynum, netname, sizeof(netname));
- BotAI_BotInitialChat(bs, "killing", netname, NULL);
- break;
- }
- case LTG_CAMP:
- case LTG_CAMPORDER:
- {
- BotAI_BotInitialChat(bs, "camping", NULL);
- break;
- }
- case LTG_PATROL:
- {
- BotAI_BotInitialChat(bs, "patrolling", NULL);
- break;
- }
- case LTG_GETFLAG:
- {
- BotAI_BotInitialChat(bs, "capturingflag", NULL);
- break;
- }
- case LTG_RUSHBASE:
- {
- BotAI_BotInitialChat(bs, "rushingbase", NULL);
- break;
- }
- case LTG_RETURNFLAG:
- {
- BotAI_BotInitialChat(bs, "returningflag", NULL);
- break;
- }
- default:
- {
- BotAI_BotInitialChat(bs, "roaming", NULL);
- break;
- }
- }
- //chat what the bot is doing
- trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
- }
-
- /*
- ==================
- BotMatch_WhatIsMyCommand
- ==================
- */
- void BotMatch_WhatIsMyCommand(bot_state_t *bs, bot_match_t *match) {
- char netname[MAX_NETNAME];
-
- ClientName(bs->client, netname, sizeof(netname));
- if (Q_stricmp(netname, bs->teamleader) != 0) return;
- bs->forceorders = qtrue;
- }
-
- /*
- ==================
- BotNearestVisibleItem
- ==================
- */
- float BotNearestVisibleItem(bot_state_t *bs, char *itemname, bot_goal_t *goal) {
- int i;
- char name[64];
- bot_goal_t tmpgoal;
- float dist, bestdist;
- vec3_t dir;
- bsp_trace_t trace;
-
- bestdist = 999999;
- i = -1;
- do {
- i = trap_BotGetLevelItemGoal(i, itemname, &tmpgoal);
- trap_BotGoalName(tmpgoal.number, name, sizeof(name));
- if (Q_stricmp(itemname, name) != 0) continue;
- VectorSubtract(tmpgoal.origin, bs->origin, dir);
- dist = VectorLength(dir);
- if (dist < bestdist) {
- //trace from start to end
- BotAI_Trace(&trace, bs->eye, NULL, NULL, tmpgoal.origin, bs->client, CONTENTS_SOLID|CONTENTS_PLAYERCLIP);
- if (trace.fraction >= 1.0) {
- bestdist = dist;
- memcpy(goal, &tmpgoal, sizeof(bot_goal_t));
- }
- }
- } while(i > 0);
- return bestdist;
- }
-
- /*
- ==================
- BotMatch_WhereAreYou
- ==================
- */
- void BotMatch_WhereAreYou(bot_state_t *bs, bot_match_t *match) {
- float dist, bestdist;
- int i, bestitem, redflagtt, blueflagtt, redtobluett;
- bot_goal_t goal;
- char *nearbyitems[] = {
- "Shotgun",
- "Grenade Launcher",
- "Rocket Launcher",
- "Plasmagun",
- "Railgun",
- "Lightning Gun",
- "BFG10K",
- "Quad Damage",
- "Regeneration",
- "Battle Suit",
- "Speed",
- "Invisibility",
- "Flight",
- "Armor",
- "Heavy Armor",
- "Red Flag",
- "Blue Flag",
- NULL
- };
- //
- if (!TeamPlayIsOn()) return;
- //if not addressed to this bot
- if (!BotAddressedToBot(bs, match)) return;
-
- bestitem = -1;
- bestdist = 999999;
- for (i = 0; nearbyitems[i]; i++) {
- dist = BotNearestVisibleItem(bs, nearbyitems[i], &goal);
- if (dist < bestdist) {
- bestdist = dist;
- bestitem = i;
- }
- }
- if (bestitem != -1) {
- if (gametype == GT_CTF) {
- redflagtt = trap_AAS_AreaTravelTimeToGoalArea(bs->areanum, bs->origin, ctf_redflag.areanum, TFL_DEFAULT);
- blueflagtt = trap_AAS_AreaTravelTimeToGoalArea(bs->areanum, bs->origin, ctf_blueflag.areanum, TFL_DEFAULT);
- redtobluett = trap_AAS_AreaTravelTimeToGoalArea(ctf_redflag.areanum, ctf_redflag.origin, ctf_blueflag.areanum, TFL_DEFAULT);
- if (redflagtt < (redflagtt + blueflagtt) * 0.4) {
- BotAI_BotInitialChat(bs, "ctflocation", nearbyitems[bestitem], "red", NULL);
- }
- else if (blueflagtt < (redflagtt + blueflagtt) * 0.4) {
- BotAI_BotInitialChat(bs, "ctflocation", nearbyitems[bestitem], "blue", NULL);
- }
- else {
- BotAI_BotInitialChat(bs, "location", nearbyitems[bestitem], NULL);
- }
- }
- else {
- BotAI_BotInitialChat(bs, "location", nearbyitems[bestitem], NULL);
- }
- trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
- }
- }
-
- /*
- ==================
- BotMatch_LeadTheWay
- ==================
- */
- void BotMatch_LeadTheWay(bot_state_t *bs, bot_match_t *match) {
- aas_entityinfo_t entinfo;
- char netname[MAX_MESSAGE_SIZE], teammate[MAX_MESSAGE_SIZE];
- int client, areanum, other;
-
- if (!TeamPlayIsOn()) return;
- //if not addressed to this bot
- if (!BotAddressedToBot(bs, match)) return;
- //if someone asks for someone else
- if (match->subtype & ST_SOMEONE) {
- //get the team mate name
- trap_BotMatchVariable(match, TEAMMATE, teammate, sizeof(teammate));
- client = FindClientByName(teammate);
- //if this is the bot self
- if (client == bs->client) {
- other = qfalse;
- }
- else if (!BotSameTeam(bs, client)) {
- //FIXME: say "I don't help the enemy"
- return;
- }
- else {
- other = qtrue;
- }
- }
- else {
- //get the netname
- trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
- client = ClientFromName(netname);
- other = qfalse;
- }
- //if the bot doesn't know who to help (FindClientByName returned -1)
- if (client < 0) {
- BotAI_BotInitialChat(bs, "whois", netname, NULL);
- trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
- return;
- }
- //
- bs->lead_teamgoal.entitynum = -1;
- BotEntityInfo(client, &entinfo);
- //if info is valid (in PVS)
- if (entinfo.valid) {
- areanum = BotPointAreaNum(entinfo.origin);
- if (areanum && trap_AAS_AreaReachability(areanum)) {
- bs->lead_teamgoal.entitynum = client;
- bs->lead_teamgoal.areanum = areanum;
- VectorCopy(entinfo.origin, bs->lead_teamgoal.origin);
- VectorSet(bs->lead_teamgoal.mins, -8, -8, -8);
- VectorSet(bs->lead_teamgoal.maxs, 8, 8, 8);
- }
- }
-
- if (bs->teamgoal.entitynum < 0) {
- if (other) BotAI_BotInitialChat(bs, "whereis", teammate, NULL);
- else BotAI_BotInitialChat(bs, "whereareyou", netname, NULL);
- trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
- return;
- }
- bs->lead_teammate = client;
- bs->lead_time = trap_AAS_Time() + TEAM_LEAD_TIME;
- bs->leadvisible_time = 0;
- bs->leadmessage_time = -(trap_AAS_Time() + 2 * random());
- }
-
- /*
- ==================
- BotMatch_Kill
- ==================
- */
- void BotMatch_Kill(bot_state_t *bs, bot_match_t *match) {
- char enemy[MAX_MESSAGE_SIZE];
- int client;
-
- if (!TeamPlayIsOn()) return;
- //if not addressed to this bot
- if (!BotAddressedToBot(bs, match)) return;
-
- trap_BotMatchVariable(match, ENEMY, enemy, sizeof(enemy));
- //
- client = FindEnemyByName(bs, enemy);
- if (client < 0) {
- BotAI_BotInitialChat(bs, "whois", enemy, NULL);
- trap_BotEnterChat(bs->cs, bs->client, CHAT_TEAM);
- return;
- }
- bs->teamgoal.entitynum = client;
- //set the time to send a message to the team mates
- bs->teammessage_time = trap_AAS_Time() + 2 * random();
- //set the ltg type
- bs->ltgtype = LTG_KILL;
- //set the team goal time
- bs->teamgoal_time = trap_AAS_Time() + TEAM_KILL_SOMEONE;
- #ifdef DEBUG
- BotPrintTeamGoal(bs);
- #endif //DEBUG
- }
-
- /*
- ==================
- BotMatch_CTF
- ==================
- */
- void BotMatch_CTF(bot_state_t *bs, bot_match_t *match) {
-
- char flag[128], netname[MAX_NETNAME];
-
- trap_BotMatchVariable(match, FLAG, flag, sizeof(flag));
- if (match->subtype & ST_GOTFLAG) {
- if (!Q_stricmp(flag, "red")) {
- bs->redflagstatus = 1;
- if (BotCTFTeam(bs) == CTF_TEAM_BLUE) {
- trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
- bs->flagcarrier = ClientFromName(netname);
- }
- }
- else {
- bs->blueflagstatus = 1;
- if (BotCTFTeam(bs) == CTF_TEAM_RED) {
- trap_BotMatchVariable(match, NETNAME, netname, sizeof(netname));
- bs->flagcarrier = ClientFromName(netname);
- }
- }
- bs->flagstatuschanged = 1;
- bs->lastflagcapture_time = trap_AAS_Time();
- }
- else if (match->subtype & ST_CAPTUREDFLAG) {
- bs->redflagstatus = 0;
- bs->blueflagstatus = 0;
- bs->flagcarrier = 0;
- bs->flagstatuschanged = 1;
- }
- else if (match->subtype & ST_RETURNEDFLAG) {
- if (!Q_stricmp(flag, "red")) bs->redflagstatus = 0;
- else bs->blueflagstatus = 0;
- bs->flagstatuschanged = 1;
- }
- }
-
- /*
- ==================
- BotMatchMessage
- ==================
- */
- int BotMatchMessage(bot_state_t *bs, char *message) {
- bot_match_t match;
-
- match.type = 0;
- //if it is an unknown message
- if (!trap_BotFindMatch(message, &match, MTCONTEXT_ENTERGAME
- |MTCONTEXT_INITIALTEAMCHAT
- |MTCONTEXT_CTF)) {
- return qfalse;
- }
- //react to the found message
- switch(match.type)
- {
- case MSG_HELP: //someone calling for help
- case MSG_ACCOMPANY: //someone calling for company
- {
- BotMatch_HelpAccompany(bs, &match);
- break;
- }
- case MSG_DEFENDKEYAREA: //teamplay defend a key area
- {
- BotMatch_DefendKeyArea(bs, &match);
- break;
- }
- case MSG_CAMP: //camp somewhere
- {
- BotMatch_Camp(bs, &match);
- break;
- }
- case MSG_PATROL: //patrol between several key areas
- {
- BotMatch_Patrol(bs, &match);
- break;
- }
- #ifdef CTF
- case MSG_GETFLAG: //ctf get the enemy flag
- {
- BotMatch_GetFlag(bs, &match);
- break;
- }
- case MSG_RUSHBASE: //ctf rush to the base
- {
- BotMatch_RushBase(bs, &match);
- break;
- }
- case MSG_RETURNFLAG:
- {
- BotMatch_ReturnFlag(bs, &match);
- break;
- }
- case MSG_CTFTASKPREFERENCE:
- {
- BotMatch_TaskPreference(bs, &match);
- break;
- }
- case MSG_CTF:
- {
- BotMatch_CTF(bs, &match);
- break;
- }
- #endif //CTF
- case MSG_GETITEM:
- {
- BotMatch_GetItem(bs, &match);
- break;
- }
- case MSG_JOINSUBTEAM: //join a sub team
- {
- BotMatch_JoinSubteam(bs, &match);
- break;
- }
- case MSG_LEAVESUBTEAM: //leave a sub team
- {
- BotMatch_LeaveSubteam(bs, &match);
- break;
- }
- case MSG_WHICHTEAM:
- {
- BotMatch_WhichTeam(bs, &match);
- break;
- }
- case MSG_CHECKPOINT: //remember a check point
- {
- BotMatch_CheckPoint(bs, &match);
- break;
- }
- case MSG_CREATENEWFORMATION: //start the creation of a new formation
- {
- trap_EA_SayTeam(bs->client, "the part of my brain to create formations has been damaged");
- break;
- }
- case MSG_FORMATIONPOSITION: //tell someone his/her position in the formation
- {
- trap_EA_SayTeam(bs->client, "the part of my brain to create formations has been damaged");
- break;
- }
- case MSG_FORMATIONSPACE: //set the formation space
- {
- BotMatch_FormationSpace(bs, &match);
- break;
- }
- case MSG_DOFORMATION: //form a certain formation
- {
- break;
- }
- case MSG_DISMISS: //dismiss someone
- {
- BotMatch_Dismiss(bs, &match);
- break;
- }
- case MSG_STARTTEAMLEADERSHIP: //someone will become the team leader
- {
- BotMatch_StartTeamLeaderShip(bs, &match);
- break;
- }
- case MSG_STOPTEAMLEADERSHIP: //someone will stop being the team leader
- {
- BotMatch_StopTeamLeaderShip(bs, &match);
- break;
- }
- case MSG_WHOISTEAMLAEDER:
- {
- BotMatch_WhoIsTeamLeader(bs, &match);
- break;
- }
- case MSG_WHATAREYOUDOING: //ask a bot what he/she is doing
- {
- BotMatch_WhatAreYouDoing(bs, &match);
- break;
- }
- case MSG_WHATISMYCOMMAND:
- {
- BotMatch_WhatIsMyCommand(bs, &match);
- break;
- }
- case MSG_WHEREAREYOU:
- {
- BotMatch_WhereAreYou(bs, &match);
- break;
- }
- case MSG_LEADTHEWAY:
- {
- BotMatch_LeadTheWay(bs, &match);
- break;
- }
- case MSG_KILL:
- {
- BotMatch_Kill(bs, &match);
- break;
- }
- case MSG_ENTERGAME: //someone entered the game
- {
- //NOTE: eliza chats will catch this
- //BotMatchVariable(&match, NETNAME, netname);
- //Com_sprintf(buf, sizeof(buf), "heya %s", netname);
- //EA_Say(bs->client, buf);
- break;
- }
- case MSG_WAIT:
- {
- break;
- }
- default:
- {
- BotAI_Print(PRT_MESSAGE, "unknown match type\n");
- break;
- }
- }
- return qtrue;
- }
-